package com.youlu.campus.service.vote;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.youlu.campus.base.exception.BusinessException;
import com.youlu.campus.common.utils.TimeUtils;
import com.youlu.campus.entity.*;
import com.youlu.campus.entity.vote.dto.UserVoteRankInfoDTO;
import com.youlu.campus.entity.vote.dto.VotePointOpDTO;
import com.youlu.campus.entity.vote.vo.VoteActivityTaskUserInfoVo;
import com.youlu.campus.entity.vote.vo.VoteActivityUserInfoVo;
import com.youlu.campus.service.activity.*;
import com.youlu.campus.service.invite.UserInviteCountService;
import com.youlu.campus.service.ranking.UserActivityPointDetailService;
import com.youlu.campus.service.ranking.UserActivityPointRankingProvinceService;
import com.youlu.campus.service.visitor.VisitorUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

import static com.youlu.campus.entity.enums.TaskBizType.INVITE;

@Service
@Slf4j
public class ActivityVoteTaskService {
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private ActivityService activityService;
    @Autowired
    private UserActivityTaskInfoService userActivityTaskInfoService;
    @Autowired
    private UserInviteCountService userInviteCountService;
    @Autowired
    private ActivityRewardRuleService activityRewardRuleService;
    @Autowired
    private UserVoteService userVoteService;
    @Autowired
    private ActivityVoteService activityVoteService;
    @Autowired
    private ActivityTaskService activityTaskService;
    @Autowired
    private VisitorUserService visitorUserService;
    @Autowired
    private UserActivityPointDetailService userActivityPointDetailService;
    @Autowired
    private UserActivityPointRankingProvinceService userActivityPointRankingProvinceService;

    /**
     * 获取票数
     * @param req
     * @return
     */
    public VoteActivityUserInfoVo getTaskInfoByUser(VoteActivityUserInfoVo req){
        log.info(":>>> 投票活动我的页面:{}", JSON.toJSONString(req));
        VoteActivityUserInfoVo voteActivityUserInfoVo = new VoteActivityUserInfoVo();
        List<ActivityTaskInfo> taskList = activityService.getTaskList(req.getActivityId());
        if(Objects.isNull(taskList)){
            return voteActivityUserInfoVo;
        }
        voteActivityUserInfoVo.setUserPO(req.getUserPO());
        voteActivityUserInfoVo.setUserInfoComplete(req.getUserInfoComplete());
        voteActivityUserInfoVo.setActivityId(req.getActivityId());
        voteActivityUserInfoVo.setAppId(req.getAppId());
        voteActivityUserInfoVo.setPlatform(req.getPlatform());
        //查询用户票数统计信息
        UserVoteRankInfoDTO userVoteRankInfo = activityVoteService.getUserVoteRankInfo(req.getActivityId(), req.getAppId(), req.getUserPO().getId(), req.getUserPO());
        if(Objects.nonNull(userVoteRankInfo)){
            voteActivityUserInfoVo.setUserVoteStatsInfo(userVoteRankInfo);
            voteActivityUserInfoVo.setVoteCaReceive(userVoteRankInfo.getVoteCaReceive());
            voteActivityUserInfoVo.setReceiveCertSuccessImageUrl(userVoteRankInfo.getReceiveCertSuccessImageUrl());
            voteActivityUserInfoVo.setInViteCaReceive(userVoteRankInfo.getInViteCaReceive());
        }
        //查询用户任务列表
        List<VoteActivityTaskUserInfoVo> voteActivityTaskUserInfoVos = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(taskList)){
            for (ActivityTaskInfo activityTaskInfo : taskList) {
                VoteActivityTaskUserInfoVo voteActivityTaskUserInfoVo = new VoteActivityTaskUserInfoVo();
                voteActivityTaskUserInfoVo.setUserId(req.getUserPO().getId());
                voteActivityTaskUserInfoVo.setActivityId(activityTaskInfo.getActivityId());
                voteActivityTaskUserInfoVo.setTaskId(activityTaskInfo.getId());
                voteActivityTaskUserInfoVo.setTaskName(activityTaskInfo.getName());
                voteActivityTaskUserInfoVo.setTaskPoints(activityTaskInfo.getPoints());
                voteActivityTaskUserInfoVo.setTaskBizType(activityTaskInfo.getTaskBizType());
                voteActivityTaskUserInfoVo.setTaskExecuteType(activityTaskInfo.getTaskExecuteType());
                voteActivityTaskUserInfoVo.setTaskLogo(activityTaskInfo.getLogo());
                voteActivityTaskUserInfoVo.setTaskTitle(activityTaskInfo.getTitle());
                voteActivityTaskUserInfoVo.setTaskSubTitle(activityTaskInfo.getSubTitle());
                voteActivityTaskUserInfoVo.setTaskButtonName(activityTaskInfo.getButtonName());
                voteActivityTaskUserInfoVo.setPriority(activityTaskInfo.getPriority());
                //判断任务执行类型一次or每日
                UserActivityTaskInfo userActivityTaskInfo;
                switch (voteActivityTaskUserInfoVo.getTaskExecuteType()) {
                    case DAILY:
                        //如有未领取
                        userActivityTaskInfo = userActivityTaskInfoService.findNotReceiveTask(req.getUserPO().getId(), voteActivityTaskUserInfoVo.getActivityId(), voteActivityTaskUserInfoVo.getTaskId(), Lists.newArrayList(0,4));
                        if(Objects.isNull(userActivityTaskInfo)) {
                            userActivityTaskInfo = userActivityTaskInfoService.find(req.getUserPO().getId(), voteActivityTaskUserInfoVo.getActivityId(), voteActivityTaskUserInfoVo.getTaskId(), TimeUtils.getDayStartTime(new Date()));
                        }
                        break;
                    default:
                        userActivityTaskInfo = userActivityTaskInfoService.find(req.getUserPO().getId(), voteActivityTaskUserInfoVo.getActivityId(), voteActivityTaskUserInfoVo.getTaskId());
                        break;
                }
                if(Objects.nonNull(userActivityTaskInfo)) {
                    voteActivityTaskUserInfoVo.setStatus(userActivityTaskInfo.getStatus());
                    voteActivityTaskUserInfoVo.setUserTaskId(userActivityTaskInfo.getId());
                }else {
                    voteActivityTaskUserInfoVo.setStatus(0);
                }
                //邀请任务
                if(INVITE.equals(activityTaskInfo.getTaskBizType())){
                    Map taskExtra = new HashMap();
                    UserInviteCount userInviteCount = userInviteCountService.find(req.getUserPO().getId(), activityTaskInfo.getActivityId(), req.getAppId(), req.getPlatform());
                    //根据余额票数查询区间证书
                    ActivityRewardRule activityRewardRule = new ActivityRewardRule();
                    Double invites = Objects.nonNull(userInviteCount)?Double.valueOf("" + userInviteCount.getCount()):0.0;
                    activityRewardRule.setToMatchValue(invites);
                    ActivityRewardRule rule = activityRewardRuleService.match(req.getActivityId(), activityTaskInfo.getId(), Boolean.FALSE, Boolean.FALSE, activityRewardRule);
                    if(Objects.nonNull(rule)){
                        taskExtra.put("caName", rule.getCaName());
                        taskExtra.put("caInvitedNumTips", rule.getInviteNumTips());
                        if(StringUtils.isNotBlank(rule.getNextCaName())){
                            taskExtra.put("caTips", String.format(rule.getTips(), new Double(rule.getNextCaQ()-activityRewardRule.getToMatchValue()).intValue(), rule.getNextCaName()));
                            taskExtra.put("nextCaName",rule.getNextCaName());
                            BigDecimal invited = new BigDecimal(activityRewardRule.getToMatchValue()-rule.getInviteStart());
                            BigDecimal inviteInterVal = new BigDecimal(rule.getNextCaQ()-rule.getInviteStart());
                            taskExtra.put("nextCaPercent", invited.divide(inviteInterVal, 2, RoundingMode.HALF_DOWN));
//                                taskExtra.put("nextCaPercent", CommonUtils.percnet(new Double(activityRewardRule.getToMatchValue()-rule.getInviteStart()).longValue(),new Double(rule.getNextCaQ()-rule.getInviteStart()).longValue()));
                            taskExtra.put("inviteButtonTips",activityTaskInfo.getInviteButtonTips());
                        }else {
                            taskExtra.put("caTips", rule.getTips());
                            taskExtra.put("nextCaName", "暂无证书");
                            taskExtra.put("nextCaPercent",0.0);
                            taskExtra.put("inviteButtonTips",activityTaskInfo.getInviteButtonTips());
                        }
                    }
                    taskExtra.put("shareInviteButtonBackGroundImgUr",activityTaskInfo.getShareInviteButtonBackGroundImgUrl());
                    taskExtra.put("shareInviteButtonType",activityTaskInfo.getShareInviteButtonType());
                    voteActivityTaskUserInfoVo.setTaskExtra(taskExtra);
                }
                voteActivityTaskUserInfoVos.add(voteActivityTaskUserInfoVo);
            }
        }
        voteActivityTaskUserInfoVos.sort(Comparator.comparing(VoteActivityTaskUserInfoVo::getPriority).reversed());
        voteActivityUserInfoVo.setTasks(voteActivityTaskUserInfoVos);
        return voteActivityUserInfoVo;
    }

    /**
     * 领取任务
     * @param userActivityTaskInfo
     * @return
     */
    public String createTask(UserActivityTaskInfo userActivityTaskInfo){
        log.info("创建活动任务，userId- > {} activityId -> {} taskId -> {}", userActivityTaskInfo.getUserId(), userActivityTaskInfo.getActivityId(),userActivityTaskInfo.getTaskId());
        if(StringUtils.isEmpty(userActivityTaskInfo.getActivityId()) || StringUtils.isEmpty(userActivityTaskInfo.getTaskId())){
            throw new BusinessException("参数错误！");
        }
        ActivityTaskInfo activityTaskInfo = activityTaskService.findById(userActivityTaskInfo.getActivityId(), userActivityTaskInfo.getTaskId());
        if(Objects.nonNull(activityTaskInfo)){
            userActivityTaskInfo.setActivityId(activityTaskInfo.getActivityId());
            userActivityTaskInfo.setDayTime(TimeUtils.getDayStartTime(new Date()));
            userActivityTaskInfo.setDoneTime(new Date());
            userActivityTaskInfo.setTaskBizType(activityTaskInfo.getTaskBizType());
            userActivityTaskInfo.setUserId(userActivityTaskInfo.getUserId());
            userActivityTaskInfo.setTaskId(activityTaskInfo.getId());
            userActivityTaskInfo.setStatus(0); //初始为待上传状态
            userActivityTaskInfo = userActivityTaskInfoService.createTaskById(userActivityTaskInfo);
            return userActivityTaskInfo.getId();
        }
        return null;
    }

    /**
     * 任务完成领取票数
     * @param userTaskId
     * @return
     */
    public Boolean receiveTaskVote(VoteActivityTaskUserInfoVo userTaskId){
        log.info("任务完成领取票数，userTaskId- > {", userTaskId);
        if(Objects.isNull(userTaskId)){
            throw new BusinessException("参数错误！");
        }
        UserActivityTaskInfo userActivityTaskInfo = userActivityTaskInfoService.find(userTaskId.getUserTaskId());
        if(Objects.isNull(userActivityTaskInfo) || userActivityTaskInfo.getStatus()!=2){
            log.error(":>>> 活动无效:{}  ", userTaskId);
            return false;
        }
        ActivityTaskInfo activityTaskInfo = activityTaskService.findById(userActivityTaskInfo.getActivityId(), userActivityTaskInfo.getTaskId());
        if (Objects.isNull(activityTaskInfo)) {
            log.error(":>>> 活动:{} 没有配置:{} 任务", userActivityTaskInfo.getActivityId(), userActivityTaskInfo.getTaskId());
            return false;
        }
        int point = activityTaskInfo.getPoints().intValue();

        VotePointOpDTO opDTO = new VotePointOpDTO();
        opDTO.setUserId(userActivityTaskInfo.getUserId());
        opDTO.setActivityId(userActivityTaskInfo.getActivityId());
        opDTO.setNum(point);
        userVoteService.updateVoteNum(opDTO);
        //添加贡献值明细，不更新排行
        UserActivityPointDetail detail = new UserActivityPointDetail();
        detail.setActivityId(userActivityTaskInfo.getActivityId());
        detail.setUserId(userActivityTaskInfo.getUserId());
        UserPO userPO = visitorUserService.getUser(userActivityTaskInfo.getUserId());
        detail.setUserPO(userPO);
        detail.setPoints(point);
        detail.setAction("add");
        detail.setBizDesc(activityTaskInfo.getName());
        detail.setBizType("vote");
        userActivityPointDetailService.create(detail);
        userActivityPointRankingProvinceService.updatePoint(userPO, userActivityTaskInfo.getActivityId(), point);
        userActivityTaskInfo.setStatus(4);
        userActivityTaskInfoService.update(userActivityTaskInfo);
        return true;
    }
}
